"""ImmApp: Immediate App Toolkit for ImGui Bundle"""

# ruff: noqa: B008, F821
from typing import Tuple, Optional, Callable, List, overload, Any
import enum
from imgui_bundle import imgui_md, hello_imgui, ImVec2, ImVec2Like
from imgui_bundle.imgui_node_editor import (
    Config as NodeEditorConfig,
    EditorContext as NodeEditorContext,
)

ImPlotFlags = int  # see implot.Flags_
ImGuiMd = imgui_md
HelloImGui = hello_imgui

VoidFunction = Callable[[], Any]
ScreenSize = Tuple[int, int]
DefaultScreenSize = (800, 600)

# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!  AUTOGENERATED CODE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# <litgen_stub> // Autogenerated code below! Do not edit!
####################    <generated_from:immapp.h>    ####################
####################    </generated_from:immapp.h>    ####################

####################    <generated_from:immapp_widgets.h>    ####################

# #ifdef IMGUI_BUNDLE_WITH_IMPLOT_AND_IMGUI_NODE_EDITOR
#
# These functions wrap ImPlot::BeginPlot and ImPlot::EndPlot,
# but they enable to make the plot content draggable inside a node
def begin_plot_in_node_editor(
    title_id: str, size: Optional[ImVec2Like] = None, flags: ImPlotFlags = 0
) -> bool:
    """Python bindings defaults:
    If size is None, then its default value will be: ImVec2(-1,0)
    """
    pass

def end_plot_in_node_editor() -> None:
    pass

def show_resizable_plot_in_node_editor(
    title_id: str,
    size_pixels: ImVec2Like,
    plot_function: VoidFunction,
    flags: ImPlotFlags = 0,
    resize_handle_size_em: float = 1.0,
) -> ImVec2:
    """ShowResizablePlotInNodeEditor: shows a resizable plot inside a node
    Returns the new size of the plot
    """
    pass

def show_resizable_plot_in_node_editor_em(
    title_id: str,
    size_em: ImVec2Like,
    plot_function: VoidFunction,
    flags: ImPlotFlags = 0,
    resize_handle_size_em: float = 1.0,
) -> ImVec2:
    """ShowResizablePlotInNodeEditor_Em: shows a resizable plot inside a node
    Returns the new size of the plot. Units are in em.
    """
    pass

# #endif

# #ifdef IMGUI_BUNDLE_WITH_IMGUI_NODE_EDITOR
#
def widget_with_resize_handle_in_node_editor(
    id: str, gui_function: VoidFunction, resize_handle_size_em: float = 1.0
) -> ImVec2:
    """WidgetWithResizeHandle_InNodeEditor: shows a resizable widget inside a node
    Returns the new size of the widget.
    """
    pass

def widget_with_resize_handle_in_node_editor_em(
    id: str, gui_function: VoidFunction, resize_handle_size_em: float = 1.0
) -> ImVec2:
    """WidgetWithResizeHandle_InNodeEditor_Em: shows a resizable widget inside a node
    Returns the new size of the widget. Size is in em.
    """
    pass

# #endif
####################    </generated_from:immapp_widgets.h>    ####################

####################    <generated_from:runner.h>    ####################
# #ifdef IMGUI_BUNDLE_WITH_IMGUI_NODE_EDITOR
#
# #endif
#

# #ifdef IMGUI_BUNDLE_WITH_IMGUI_NODE_EDITOR
#
# #endif
#

class AddOnsParams:
    """///////////////////////////////////////////////////////////////////////////////////////

     AddOnParams: require specific ImGuiBundle packages (markdown, node editor, texture viewer)
     to be initialized at startup.

    /////////////////////////////////////////////////////////////////////////////////////
    """

    # Set withImplot=True if you need to plot graphs with implot
    with_implot: bool = False
    # Set withImplot3=True if you need to plot 3 graphs with implot3
    with_implot3d: bool = False

    # Set withMarkdown=True if you need to render Markdown
    # (alternatively, you can set withMarkdownOptions)
    with_markdown: bool = False

    # Set withNodeEditor=True if you need to render a node editor
    # (alternatively, you can set withNodeEditorConfig)
    with_node_editor: bool = False

    # Set withTexInspect=True if you need to use imgui_tex_inspect
    with_tex_inspect: bool = False

    # #ifdef IMGUI_BUNDLE_WITH_IMGUI_NODE_EDITOR
    #
    # You can tweak NodeEditorConfig (but this is optional)
    with_node_editor_config: Optional[NodeEditorConfig] = None

    # If True, the node editor colors will be updated from the ImGui colors
    # (i.e. if using a light theme, the node editor will use a light theme, etc.)
    # This is called after runnerParams.callbacks.SetupImGuiStyle, in which you can set the ImGui style.
    # If you set this to False, you can set the node editor style manually.
    # (Note: you can also the theme via RunnerParams.imguiParams.tweakedTheme)
    update_node_editor_colors_from_imgui_colors: bool = True
    # #endif
    #

    # You can tweak MarkdownOptions (but this is optional)
    with_markdown_options: Optional[ImGuiMd.MarkdownOptions] = None
    def __init__(
        self,
        with_implot: bool = False,
        with_implot3d: bool = False,
        with_markdown: bool = False,
        with_node_editor: bool = False,
        with_tex_inspect: bool = False,
        with_node_editor_config: Optional[NodeEditorConfig] = None,
        update_node_editor_colors_from_imgui_colors: bool = True,
        with_markdown_options: Optional[ImGuiMd.MarkdownOptions] = None,
    ) -> None:
        """Auto-generated default constructor with named params"""
        pass

# ///////////////////////////////////////////////////////////////////////////////////////
#
# Helpers to run an app from C++
#
# /////////////////////////////////////////////////////////////////////////////////////
# Run an application using HelloImGui params + some addons
@overload
def run(
    runner_params: HelloImGui.RunnerParams,
    add_ons_params: Optional[AddOnsParams] = None,
) -> None:
    """Python bindings defaults:
    If addOnsParams is None, then its default value will be: AddOnsParams()
    """
    pass

@overload
def run(
    simple_params: HelloImGui.SimpleRunnerParams,
    add_ons_params: Optional[AddOnsParams] = None,
) -> None:
    """Python bindings defaults:
    If addOnsParams is None, then its default value will be: AddOnsParams()
    """
    pass

@overload
def run(
    gui_function: VoidFunction,
    window_title: str = "",
    window_size_auto: bool = False,
    window_restore_previous_geometry: bool = False,
    window_size: Optional[ScreenSize] = None,
    fps_idle: float = 10.0,
    with_implot: bool = False,
    with_implot3d: bool = False,
    with_markdown: bool = False,
    with_node_editor: bool = False,
    with_tex_inspect: bool = False,
    with_node_editor_config: Optional[NodeEditorConfig] = None,
    with_markdown_options: Optional[ImGuiMd.MarkdownOptions] = None,
) -> None:
    """///////////////////////////////////////////////////////////////////////////////////////

     Helpers to run an app from Python (using named parameters)

    /////////////////////////////////////////////////////////////////////////////////////
     Helper to run an app inside imgui_bundle, using HelloImGui:

     (HelloImGui::SimpleRunnerParams)
         - `guiFunction`: the function that will render the ImGui widgets
         - `windowTitle`: title of the window
         - `windowSizeAuto`: if True, autosize the window from its inner widgets
         - `windowRestorePreviousGeometry`: if True, restore window size and position from last run
         - `windowSize`: size of the window
         - `fpsIdle`: fps of the application when idle

     (ImmApp::AddOnsParams)
         - `with_implot`: if True, then a context for implot will be created/destroyed automatically
         - `with_markdown` / `with_markdown_options`: if specified, then  the markdown context will be initialized
           (i.e. required fonts will be loaded)
         - `with_node_editor` / `with_node_editor_config`: if specified, then a context for imgui_node_editor
           will be created automatically.


    Python bindings defaults:
        If windowSize is None, then its default value will be: DefaultWindowSize
    """
    pass

def run_with_markdown(
    gui_function: VoidFunction,
    window_title: str = "",
    window_size_auto: bool = False,
    window_restore_previous_geometry: bool = False,
    window_size: Optional[ScreenSize] = None,
    fps_idle: float = 10.0,
    with_implot: bool = False,
    with_implot3d: bool = False,
    with_node_editor: bool = False,
    with_tex_inspect: bool = False,
    with_node_editor_config: Optional[NodeEditorConfig] = None,
    with_markdown_options: Optional[ImGuiMd.MarkdownOptions] = None,
) -> None:
    """Run an application with markdown


    Python bindings defaults:
        If windowSize is None, then its default value will be: DefaultWindowSize
    """
    pass

# ///////////////////////////////////////////////////////////////////////////////////////
#
# Dpi aware utilities (which call the same utilities from HelloImGui)
#
# /////////////////////////////////////////////////////////////////////////////////////

@overload
def em_size() -> float:
    """EmSize() returns the visible font size on the screen. For good results on HighDPI screens, always scale your
    widgets and windows relatively to this size.
    It is somewhat comparable to the [em CSS Unit](https://lyty.dev/css/css-unit.html).
    EmSize() = ImGui::GetFontSize()
    """
    pass

@overload
def em_size(nb_lines: float) -> float:
    """EmSize(nbLines) returns a size corresponding to nbLines text lines"""
    pass

# EmToVec2() returns an ImVec2 that you can use to size or place your widgets in a DPI independent way
# (pass sizes that are proportional to the font height)
@overload
def em_to_vec2(x: float, y: float) -> ImVec2:
    pass

@overload
def em_to_vec2(v: ImVec2Like) -> ImVec2:
    pass

def pixels_to_em(pixels: ImVec2Like) -> ImVec2:
    """PixelsToEm() converts a Vec2 in pixels to a Vec2 in em"""
    pass

def pixel_size_to_em(pixel_size: float) -> float:
    """PixelSizeToEm() converts a size in pixels to a size in em"""
    pass

# ///////////////////////////////////////////////////////////////////////////////////////
#
# Utility for ImGui node editor & NanoVG
#
# /////////////////////////////////////////////////////////////////////////////////////
# #ifdef IMGUI_BUNDLE_WITH_IMGUI_NODE_EDITOR
#
def default_node_editor_context() -> NodeEditorContext:
    pass

def default_node_editor_config() -> NodeEditorConfig:
    pass

def node_editor_settings_location(runner_params: HelloImGui.RunnerParams) -> str:
    """NodeEditorSettingsLocation returns the path to the json file for the node editor settings."""
    pass

def has_node_editor_settings(runner_params: HelloImGui.RunnerParams) -> bool:
    """HasNodeEditorSettings returns True if the json file for the node editor settings exists."""
    pass

def delete_node_editor_settings(runner_params: HelloImGui.RunnerParams) -> None:
    """DeleteNodeEditorSettings deletes the json file for the node editor settings."""
    pass

# #endif
#

# =========================== HelloImGui::ManualRender ==================================
# @@md#HelloImGui::ManualRender

# @@md

# <submodule manual_render>
class manual_render:  # Proxy class that introduces typings for the *submodule* manual_render
    pass  # (This corresponds to a C++ namespace. All methods are static!)
    """ namespace ManualRender"""
    # Immapp::ManualRender is a namespace that groups functions, allowing fine-grained control over the rendering process:
    # - It is customizable like Immapp::Run: initialize it with `RunnerParams` and `AddOnsParams`.
    # - `ManualRender::Render()` will render the application for one frame:
    # - Ensure that `ManualRender::Render()` is triggered regularly (e.g., through a loop or other mechanism)
    #   to maintain responsiveness. This method must be called on the main thread.

    @staticmethod
    def setup_from_runner_params(
        runner_params: HelloImGui.RunnerParams,
        add_ons_params: Optional[AddOnsParams] = None,
    ) -> None:
        """Initializes the rendering with the full customizable `RunnerParams`.
         This will initialize the platform backend (SDL, Glfw, etc.) and the rendering backend (OpenGL, Vulkan, etc.).
         A distinct copy of `RunnerParams` is stored internally.


        Python bindings defaults:
            If addOnsParams is None, then its default value will be: AddOnsParams()
        """
        pass

    @staticmethod
    def setup_from_simple_runner_params(
        simple_params: HelloImGui.SimpleRunnerParams,
        add_ons_params: Optional[AddOnsParams] = None,
    ) -> None:
        """Initializes the rendering with `SimpleRunnerParams`.
         This will initialize the platform backend (SDL, Glfw, etc.) and the rendering backend (OpenGL, Vulkan, etc.).


        Python bindings defaults:
            If addOnsParams is None, then its default value will be: AddOnsParams()
        """
        pass

    @staticmethod
    def setup_from_gui_function(
        gui_function: VoidFunction,
        window_title: str = "",
        window_size_auto: bool = False,
        window_restore_previous_geometry: bool = False,
        window_size: Optional[ScreenSize] = None,
        fps_idle: float = 10.0,
        with_implot: bool = False,
        with_implot3d: bool = False,
        with_markdown: bool = False,
        with_node_editor: bool = False,
        with_tex_inspect: bool = False,
        with_node_editor_config: Optional[NodeEditorConfig] = None,
        with_markdown_options: Optional[ImGuiMd.MarkdownOptions] = None,
    ) -> None:
        """Initializes the renderer with a simple GUI function and additional parameters.
         This will initialize the platform backend (SDL, Glfw, etc.) and the rendering backend (OpenGL, Vulkan, etc.).


        Python bindings defaults:
            If windowSize is None, then its default value will be: DefaultWindowSize
        """
        pass

    @staticmethod
    def render() -> None:
        """Renders the current frame. Should be called regularly to maintain the application's responsiveness."""
        pass

    @staticmethod
    def tear_down() -> None:
        """Tears down the renderer and releases all associated resources.
        This will release the platform backend (SDL, Glfw, etc.) and the rendering backend (OpenGL, Vulkan, etc.).
        After calling `TearDown()`, the InitFromXXX can be called with new parameters.
        """
        pass

# </submodule manual_render>
####################    </generated_from:runner.h>    ####################

####################    <generated_from:clock.h>    ####################

def clock_seconds() -> float:
    """Chronometer in seconds"""
    pass

####################    </generated_from:clock.h>    ####################

####################    <generated_from:code_utils.h>    ####################

# <submodule code_utils>
class code_utils:  # Proxy class that introduces typings for the *submodule* code_utils
    pass  # (This corresponds to a C++ namespace. All methods are static!)
    """ namespace CodeUtils"""

    @staticmethod
    def unindent(code: str, is_markdown: bool) -> str:
        pass

    @staticmethod
    def unindent_code(code: str) -> str:
        pass

    @staticmethod
    def unindent_markdown(code: str) -> str:
        pass

# </submodule code_utils>
####################    </generated_from:code_utils.h>    ####################

####################    <generated_from:snippets.h>    ####################

# <submodule snippets>
class snippets:  # Proxy class that introduces typings for the *submodule* snippets
    pass  # (This corresponds to a C++ namespace. All methods are static!)
    #
    # TextEditorBundle: addition to ImGuiColorTextEdit, specific to ImGuiBundle
    #

    class SnippetLanguage(enum.IntEnum):
        cpp = enum.auto()  # (= 0)
        hlsl = enum.auto()  # (= 1)
        glsl = enum.auto()  # (= 2)
        c = enum.auto()  # (= 3)
        sql = enum.auto()  # (= 4)
        angel_script = enum.auto()  # (= 5)
        lua = enum.auto()  # (= 6)
        python = enum.auto()  # (= 7)

    class SnippetTheme(enum.IntEnum):
        dark = enum.auto()  # (= 0)
        light = enum.auto()  # (= 1)
        retro_blue = enum.auto()  # (= 2)
        mariana = enum.auto()  # (= 3)

    @staticmethod
    def default_snippet_language() -> SnippetLanguage:
        """DefaultSnippetLanguage will be Cpp or Python if using python bindings."""
        pass

    class SnippetData:
        code: str = ""
        language: SnippetLanguage = DefaultSnippetLanguage()
        palette: SnippetTheme = SnippetTheme.light

        show_copy_button: bool = (
            True  # Displayed on top of the editor (Top Right corner)
        )
        show_cursor_position: bool = True  # Show line and column number
        displayed_filename: str = ""  # Displayed on top of the editor

        height_in_lines: int = 0  # Number of visible lines in the editor
        max_height_in_lines: int = (
            40  # If the number of lines in the code exceeds this, the editor will scroll. Set to 0 to disable.
        )

        read_only: bool = False  # Snippets are read-only by default

        border: bool = False  # Draw a border around the editor

        de_indent_code: bool = (
            True  # Keep the code indentation, but remove main indentation,
        )
        # so that the displayed code start at column 1

        add_final_empty_line: bool = (
            False  # Add an empty line at the end of the code if missing
        )
        def __init__(
            self,
            code: str = "",
            language: SnippetLanguage = DefaultSnippetLanguage(),
            palette: SnippetTheme = SnippetTheme.light,
            show_copy_button: bool = True,
            show_cursor_position: bool = True,
            displayed_filename: str = "",
            height_in_lines: int = 0,
            max_height_in_lines: int = 40,
            read_only: bool = False,
            border: bool = False,
            de_indent_code: bool = True,
            add_final_empty_line: bool = False,
        ) -> None:
            """Auto-generated default constructor with named params"""
            pass

    @staticmethod
    def show_editable_code_snippet(
        label_id: str,
        snippet_data: SnippetData,
        width: float = 0.0,
        override_height_in_lines: int = 0,
    ) -> bool:
        pass

    @staticmethod
    def show_code_snippet(
        snippet_data: SnippetData, width: float = 0.0, override_height_in_lines: int = 0
    ) -> None:
        pass

    @staticmethod
    @overload
    def show_side_by_side_snippets(
        snippet1: SnippetData,
        snippet2: SnippetData,
        hide_if_empty: bool = True,
        equal_visible_lines: bool = True,
    ) -> None:
        pass

    @staticmethod
    @overload
    def show_side_by_side_snippets(
        snippets: List[SnippetData],
        hide_if_empty: bool = True,
        equal_visible_lines: bool = True,
    ) -> None:
        pass

# </submodule snippets>
####################    </generated_from:snippets.h>    ####################

# </litgen_stub> // Autogenerated code end!
